package com.ashafa.server;

import java.io.File;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.servlet.ServletHolder;
import org.mortbay.jetty.servlet.Context;
import org.mortbay.jetty.ajp.Ajp13SocketConnector;
import org.mortbay.jetty.handler.ResourceHandler;
import org.mortbay.jetty.nio.SelectChannelConnector;
import org.mortbay.thread.QueuedThreadPool;

import org.apache.log4j.*;

public class ServerStart {
	
	private static final Logger logger = Logger.getLogger(ServerStart.class.getName()); //Logger.getLogger(); 

	
	public static void main(String[] args) throws Exception	{
		
		String installPath = System.getProperty("ashafa.home");
		String protocol;
		
		if(installPath == null){
			installPath = System.getProperty("user.dir");
		}
		System.setProperty("file.encoding", "UTF-8");
		String loggerProperties = installPath + "/logger.properties";
		if(new File(loggerProperties).exists()){
			System.out.println("log4j:INFO Intializing log4j: " + loggerProperties);
			PropertyConfigurator.configure(loggerProperties);
			
		} else {
			BasicConfigurator.configure();
			Logger.getLogger("org.mortbay.log").setLevel(Level.WARN);
			logger.warn("'logger.properties' not found in install directory. Using default logger configuration.");
		}
		
		Properties properties = new Properties();
	    try {
	    	properties.load(new FileInputStream(installPath + "/server.properties"));
	    } catch (IOException e) {
	    	logger.warn("'server.properties' not found in installation directory. Using default server properties.", e);
	    }
	    
	   
	    int port = 8080;
	    String contextsPath = installPath + "/contexts"; 
		String resourceBasePath = installPath + "/web-files/static";
		
		Server server;
		
		if(properties.get("server.port")!=null)
			port = Integer.parseInt((String)properties.get("server.port"));
		
		if(properties.get("server.static")!=null)
			resourceBasePath = (String)properties.get("server.static");
		
		if(properties.get("server.contexts")!=null)
			contextsPath = (String)properties.get("server.contexts");
		
		server = new Server();
		
		QueuedThreadPool threadPool = new QueuedThreadPool();
		threadPool.setMaxThreads(100);
		server.setThreadPool(threadPool);
		
		File contextsDirectory = new File(contextsPath);
		String [] contextsDirectoryList = contextsDirectory.list();
		
		Servlet.setContextsPath(contextsPath);
		Servlet.setInstallPath(installPath);
		
		for (int i = 0; i < contextsDirectoryList.length; i++)
		{
			try
			{
				if((!contextsDirectoryList[i].equals("static") && !contextsDirectoryList[i].equals("admin")) && new File(contextsPath + "/"+contextsDirectoryList[i]).isDirectory() && new File(contextsPath + "/"+contextsDirectoryList[i] + "/urls.json").exists())
				{
					Context context = new Context(server,"/"+contextsDirectoryList[i], Context.SESSIONS);
			 		if(properties.get("server.clear-cookie-path") != null && ((String)properties.get("clear-cookie-path")).equals("true"))
			 		{
			 			context.getSessionHandler().getSessionManager().setSessionPath("/");
			 		}
			 		context.addServlet(new ServletHolder(new Servlet()), "/*");
			 		context.setErrorHandler(new CustomErrorHandler(true, true));
			 		logger.info("'/"+contextsDirectoryList[i] + "' initialized successfully.");
			 	}
				
				
			} catch(Exception e) {
				logger.warn(" failed to start.", e);
			}
		}    
		
		
		
		if(properties.get("server.protocol") != null && ((String)properties.get("server.protocol")).equals("ajp"))
		{
			protocol = "ajp";
			Connector ajpConnector = new Ajp13SocketConnector();
			ajpConnector.setPort(port);
			server.setConnectors(new Connector[] {ajpConnector});
			
		} else {
			protocol = "http";
			Connector connector = new SelectChannelConnector();
		    connector.setPort(port);
		    connector.setMaxIdleTime(30000);
		    server.setConnectors(new Connector[]{connector});
			
			ResourceHandler resourceHandler = new ResourceHandler();
			resourceHandler.setResourceBase(resourceBasePath);
			Context staticContext = new Context(server,"/" + resourceBasePath.split("/")[resourceBasePath.split("/").length - 1], 0);
			staticContext.setHandler(resourceHandler);
			staticContext.setErrorHandler(new CustomErrorHandler(false, false));
			
		}
				
		Context rootContext = new Context(server,"/", 0);
		rootContext.setHandler(new CustomDefaultHandler());
		rootContext.setErrorHandler(new CustomErrorHandler(false, false));
			
		server.start();
		logger.info("Server started with '" + protocol+ "' on "  + port + ". Happy Hacking!");
		server.join();
		
	}
}
